home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
SNNSV32.ZIP
/
SNNSv3.2
/
kernel
/
sources
/
update_f.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-25
|
62KB
|
2,138 lines
/*****************************************************************************
FILE : update_f.c
SHORTNAME :
SNNS VERSION : 3.2
PURPOSE : SNNS-Kernel Network Update Functions
NOTES :
AUTHOR : Niels Mache
DATE : 18.03.91
CHANGED BY : Sven Doering, Michael Vogt (Martin Reczko)
IDENTIFICATION : @(#)update_f.c 1.21 3/15/94
SCCS VERSION : 1.21
LAST CHANGE : 3/15/94
Copyright (c) 1990-1994 SNNS Group, IPVR, Univ. Stuttgart, FRG
******************************************************************************/
#include <stdio.h>
#include <math.h>
#include <values.h>
#include "kr_typ.h" /* Kernel Types and Constants */
#include "kr_const.h" /* Constant Declarators for SNNS-Kernel */
#include "kr_def.h" /* Default Values */
#include "kernel.h" /* Kernel Functions */
#include "glob_typ.h"
#include "kr_ui.h"
#include "kr_mem.h" /* Memory Manager Functions */
#include "random.h" /* Randomize Library Function Prototypes */
#include "kr_mac.h" /* Kernel Macros */
#include "krart_df.h" /* Macros and Definitions for ART */
#include "kr_art1.h"
#include "kr_art2.h"
#include "kr_amap.h"
#include "kr_art.h" /* Function Prototypes of ART kernel functions */
#include "kr_td.h" /* Function Prototypes of Time Delay functions */
#include "rcc_learn.h"
#include "cc_rcc.h"
#include "cc_mac.h"
#include "dlvq_learn.h"
#include "update_f.ph"
#include "kr_JordElm.h"
#include "func_mac.h"
/*#################################################
GROUP: Update Functions
#################################################*/
/*****************************************************************************
FUNCTION : UPDATE_syncPropagate
PURPOSE : synchronous propagation
RETURNS :
NOTES :
UPDATE : 01.12.93
******************************************************************************/
krui_err UPDATE_syncPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
/* update unit activations first */
FOR_ALL_UNITS( unit_ptr )
if ( !IS_INPUT_UNIT( unit_ptr) && UNIT_IN_USE( unit_ptr ))
/* unit isn't an input unit and is in use and enabled */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
/* update unit outputs */
FOR_ALL_UNITS( unit_ptr )
if UNIT_IN_USE( unit_ptr )
/* unit is in use and enabled */
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_serialPropagate
PURPOSE : serial propagation
RETURNS :
NOTES :
UPDATE : 01.12.93
******************************************************************************/
krui_err UPDATE_serialPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
/* update unit activations and outputs */
FOR_ALL_UNITS( unit_ptr )
if UNIT_IN_USE( unit_ptr ){
/* unit is in use and enabled */
if (!IS_INPUT_UNIT( unit_ptr ))
/* this isn't a input unit: calculate the activation of
the unit by calling the activation function */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_randomOrderPropagate
PURPOSE : random order propagation
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_randomOrderPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr, *u_array;
register int no_of_units;
int n;
u_array = unit_array;
no_of_units = NoOfUnits;
for (n = 0; n < no_of_units; n++){
/* choose unit */
unit_ptr = u_array + (1 + lrand48() % no_of_units);
if (!IS_INPUT_UNIT( unit_ptr ))
/* this isn't a input unit: calculate the activation of the unit by
calling the activation function */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_randomPermutPropagate
PURPOSE : random permutation propagation
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_randomPermutPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
register TopoPtrArray topo_ptr;
int ret_code;
if (NetModified || (TopoSortID != PERMUTATION)){
/* networt was modified or permutation array isn't initialized */
ret_code = kr_makeUnitPermutation();
if (ret_code != KRERR_NO_ERROR)
return( ret_code );
}
topo_ptr = topo_ptr_array;
/* propagate net */
while ((unit_ptr = *++topo_ptr) != NULL){
if (!IS_INPUT_UNIT( unit_ptr ))
/* this isn't a input unit: calculate the activation of the unit
by calling the activation function */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_topologicalPropagate
PURPOSE : Propagate Units in topological order
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_topologicalPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
register TopoPtrArray topo_ptr;
int ret_code;
if (NetModified || (TopoSortID != TOPOLOGICAL_FF)){
/* networt was modified or topologic array isn't initialized */
ret_code = kr_topoSort( TOPOLOGICAL_FF );
if (ret_code != KRERR_NO_ERROR)
return( ret_code );
NetModified = FALSE;
}
topo_ptr = topo_ptr_array + 1;
/* propagate input units only */
while ((unit_ptr = *topo_ptr++) != NULL){
/* input units, don't call the activation function */
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
/* propagate hidden units only */
while ((unit_ptr = *topo_ptr++) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
/* propagate output units only */
while ((unit_ptr = *topo_ptr++) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call the output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_KohonenPropagate
PURPOSE : Propagate Units in topological order for Kohonen networks
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_KohonenPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
register TopoPtrArray topo_ptr;
int ret_code;
if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
/* networt was modified or topologic array isn't initialized */
ret_code = kr_topoSort( TOPOLOGIC_TYPE );
if (ret_code = KRERR_NO_OUTPUT_UNITS) ret_code = KRERR_NO_ERROR;
if (ret_code != KRERR_NO_ERROR)
return( ret_code );
NetModified = FALSE;
}
topo_ptr = topo_ptr_array + 1;
/* propagate input units only */
while ((unit_ptr = *topo_ptr++) != NULL){
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
/* propagate hidden units only */
while ((unit_ptr = *topo_ptr++) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : normalize_inputvector
PURPOSE : normalize input vector for Counterpropagation Update Function
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
static void normalize_inputvector(float sum)
{
register struct Unit *unit_ptr;
register float amount;
amount = 1.0 / sqrt( sum );
FOR_ALL_UNITS( unit_ptr )
if (IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
/* this is a input unit */
unit_ptr->Out.output = unit_ptr->Out.output * amount;
}
/*****************************************************************************
FUNCTION : UPDATE_CPNPropagate
PURPOSE : Counterpropagation Update Function
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_CPNPropagate(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr, *winner_ptr;
register struct Site *site_ptr;
register struct Link *link_ptr;
register TopoPtrArray topo_ptr;
float maximum, unit_ptr_net, sum;
int ret_code;
if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
/* networt was modified or topologic array isn't initialized */
ret_code = kr_topoSort( TOPOLOGIC_TYPE );
if (ret_code != KRERR_NO_ERROR)
return( ret_code );
NetModified = FALSE;
}
topo_ptr = topo_ptr_array;
sum = 0.0;
/* propagagate all input units */
while ((unit_ptr = *++topo_ptr) != NULL){
/* this is an input unit */
unit_ptr->Out.output = unit_ptr->act;
sum += unit_ptr->Out.output * unit_ptr->Out.output;
}
if (sum != 0.0)
/* normalize the inputvector */
normalize_inputvector( sum );
/* propagate Kohonen Layer */
/* calculate the activation and the output values
of the hidden units (Kohonen Layer) */
winner_ptr = NULL;
maximum = -1.0e30; /* contains the maximum of the activations */
/* propagagate all hidden units */
while ((unit_ptr = *++topo_ptr) != NULL){
/* this is a hidden unit */
unit_ptr_net = 0.0;
if (unit_ptr->flags & UFLAG_SITES){
/* the unit has sites */
FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
unit_ptr_net += (link_ptr->weight * link_ptr->to->Out.output);
}else{ /* the unit has direct links */
FOR_ALL_LINKS( unit_ptr, link_ptr )
unit_ptr_net += (link_ptr->weight * link_ptr->to->Out.output);
}
if (maximum < unit_ptr_net){ /* determine winner unit */
winner_ptr = unit_ptr;
maximum = unit_ptr_net;
}
/* reset output and activation of hidden units */
unit_ptr->Out.output = unit_ptr->act = (FlintType) 0;
}
/* the competitive winner is chosen */
winner_ptr->Out.output = winner_ptr->act = (FlintType) 1;
/* propagate the Grossberg Layer */
/* propagagate all output units */
while ((unit_ptr = *++topo_ptr) != NULL){ /* this is a output unit */
/* the activation function is the identity function ( weighted sum) */
unit_ptr->Out.output = unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_TimeDelayPropagate
PURPOSE :
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_TimeDelayPropagate(float parameterArray[], int NoOfParams )
{
register struct Unit *unit_ptr;
register TopoPtrArray topo_ptr;
int ret_code;
/* initialization if necessary */
if (NetModified || (TopoSortID != TOPOLOGIC_LOGICAL)){
/* Net has been modified or topologic array isn't initialized */
/* check the topology of the network */
/* first: save the logical layer numbers, restore them after check */
FOR_ALL_UNITS(unit_ptr)
unit_ptr -> Aux.int_no = unit_ptr -> lln;
ret_code = kr_topoCheck();
FOR_ALL_UNITS(unit_ptr)
unit_ptr -> lln = unit_ptr -> Aux.int_no;
if (ret_code < KRERR_NO_ERROR)
return( ret_code ); /* an error has occured */
if (ret_code < 2)
return( KRERR_NET_DEPTH ); /* the network has less then 2 layers */
/* count the no. of I/O units and check the patterns */
ret_code = kr_IOCheck();
if (ret_code < KRERR_NO_ERROR) return( ret_code );
ret_code = kr_topoSort( TOPOLOGIC_LOGICAL );
if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
return( ret_code );
NetModified = FALSE;
}
topo_ptr = topo_ptr_array;
unit_ptr = *++topo_ptr;
/* propagate input units only */
while (unit_ptr != (struct Unit *) NULL){
/* input units doesn't have inputs, so don't call the
activation function */
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: there is no need to call the
output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* no identity output function: calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
unit_ptr = *++topo_ptr;
}
/* use the propagation function of the learning function for the update */
/* This way, the necessary time delay code is present only once */
/* Use the special pattern_no -1, to prevent loading of a pattern */
propagateTDNetForward(-1,-1);
return (KRERR_NO_ERROR);
} /* UPDATE_TimeDelayPropagate */
/*****************************************************************************
FUNCTION : UPDATE_ART1_syncPropagate
PURPOSE : ART 1 update function which does exactly the same as the normal
synchronous propagate function except that additionally the winner
of the ART 1 recognition layer is calculated.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_ART1_syncPropagate(float *parameterArray, int NoOfParams)
{
krui_err ret_code = KRERR_NO_ERROR;
int i;
struct Unit *winner_ptr; /* recognition unit which is the winner of w.t.a*/
struct Unit *unit_ptr;
TopoPtrArray topo_layer[6]; /* topo_layer[0] : *first input unit
topo_layer[1] : *first comp. unit
topo_layer[2] : *first rec. unit
topo_layer[3] : *first delay unit
topo_layer[4] : *first local reset unit
topo_layer[5] : *first special unit
(classified_unit)*/
TopoPtrArray topo_ptr;
static float rho;
bool inp_pat_changed = FALSE;
bool rho_has_changed = FALSE;
/* Check vigilance parameter */
if (NoOfParams < 1) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
} /*if*/
/* Check if rho has changed from last to actual call of this update function
If rho has changed, then put new activation value into unit rho */
if (rho != parameterArray[0]) {
rho_has_changed = TRUE;
}
rho = parameterArray[0];
if ((rho < 0.0) || (rho > 1.0)) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* Check if network has been modified or learning function has just
been changed */
if (NetModified || (TopoSortID != ART1_TOPO_TYPE)) {
(void) kr_topoSort (ART1_TOPO_TYPE);
ret_code = KernelErrorCode;
if (ret_code != KRERR_NO_ERROR) {
NetModified = TRUE;
return (ret_code);
} /*if*/
NetModified = FALSE;
}
/* get pointers to resep. first elements of each layer in topo_ptr_array */
topo_ptr = topo_ptr_array+1;
for(i=0; i<=5; i++){
topo_layer[i] = topo_ptr;
do {
} while (*topo_ptr++ != NULL);
}
/* Check if input pattern changed since last call to this function */
if (krart_inp_pat_changed(topo_layer[0])) {
inp_pat_changed = TRUE;
krart_save_inp_pat(topo_layer[0]);
}
/* Push activation of input units to their output value.
This is important for the first cycle. */
topo_ptr = topo_layer[0];
for (unit_ptr = *topo_ptr; *topo_ptr != NULL; unit_ptr = *topo_ptr++) {
if (unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
} else {
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
}
/* if rho had changed from last to this call of this update function then
reinitialize the values of the i_act field of the unit structure and
reset the activations of all non input units */
if (rho_has_changed || inp_pat_changed) {
ret_code = kra1_init_i_act (rho);
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
ret_code = krart_reset_activations ();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
}
/* 1 propagation step (all units push their information onto
their output and calculate their new activation.*/
krart_prop_synch ();
/* look for the recognition unit with the highest activation
returns a NULL pointer if all recognition units have
activation 0.0 */
winner_ptr = krart_get_winner (topo_layer[2],1.0);
return (ret_code);
}
/*****************************************************************************
FUNCTION : UPDATE_ART1_Propagate
PURPOSE : ART1 Update function for updating until a stable state is reached,
e.g. either the 'classified' unit is on or the 'not classifiable'
unit is.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_ART1_Propagate(float *parameterArray, int NoOfParams)
{
krui_err ret_code = KRERR_NO_ERROR;
int i;
struct Unit *winner_ptr; /* recogn. unit which is the winner of w.t.a */
TopoPtrArray topo_layer[6]; /* topo_layer[0] : *first input unit
topo_layer[1] : *first comp. unit
topo_layer[2] : *first rec. unit
topo_layer[3] : *first delay unit
topo_layer[4] : *first local reset unit
topo_layer[5] : *first special unit
(classified_unit) */
TopoPtrArray topo_ptr;
float rho;
/* Check vigilance parameter */
if (NoOfParams < 1) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
rho = parameterArray[0];
if ((rho < 0.0) || (rho > 1.0)) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* Check if network has been modified or learning function has just
been changed */
if (NetModified || (TopoSortID != ART1_TOPO_TYPE)) {
(void) kr_topoSort (ART1_TOPO_TYPE);
ret_code = KernelErrorCode;
if (ret_code != KRERR_NO_ERROR) {
NetModified = TRUE;
return (ret_code);
}
NetModified = FALSE;
}
ret_code = kra1_init_i_act (rho);
if (ret_code != KRERR_NO_ERROR) {
return (ret_code);
}
/* get pointers to resp. first elements of each layer in topo_ptr_array */
topo_ptr = topo_ptr_array+1;
for (i=0; i<=5; i++) {
topo_layer[i] = topo_ptr;
do {
} while (*topo_ptr++ != NULL);
}
/* initialize activations of non input units */
ret_code = krart_reset_activations ();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
do {
/* 1 propagation step (all units push their information onto
their output and calculate their new activation */
krart_prop_synch ();
/* look for the recognition unit with the highest activation
returns a NULL pointer if all recognition units have
activation 0.0 */
winner_ptr = krart_get_winner (topo_layer[2],1.0);
} while (!(ART1_CLASSIFIED) && !(ART1_NOT_CLASSIFIABLE));
return (ret_code);
}
/*****************************************************************************
FUNCTION : UPDATE_ART2_syncPropagate
PURPOSE : ART 2 update function which does exactly the same as the normal
synchronous propagate function except that additionally the winner
of the ART 1 recognition layer is calculated.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_ART2_syncPropagate(float *parameterArray, int NoOfParams)
{
krui_err ret_code = KRERR_NO_ERROR;
int i;
struct Unit *winner_ptr; /* recogn. unit which is the winner of w.t.a */
struct Unit *unit_ptr;
TopoPtrArray topo_layer[12]; /* topo_layer[0] : *first input unit
topo_layer[1] : *first w unit
topo_layer[2] : *first x unit
topo_layer[3] : *first u unit
topo_layer[4] : *first v unit
topo_layer[5] : *first p unit
topo_layer[6] : *first q unit
topo_layer[7] : *first r unit
topo_layer[8] : *first rec. unit
topo_layer[9] : *first local reset unit */
TopoPtrArray topo_ptr;
static float rho, param_a, param_b, param_c, param_d, theta;
bool inp_pat_changed = FALSE;
bool rho_has_changed = FALSE;
bool a_has_changed = FALSE;
bool b_has_changed = FALSE;
bool c_has_changed = FALSE;
bool theta_has_changed = FALSE;
/* Check vigilance parameter */
if (NoOfParams < 5) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* Check if input pattern had changed from last step to this one */
/* Check if one of the parameters has changed from last to actual
call of this update function.
If so, then put new activation value into unit rho or change
the weights of the relevant links. */
if (rho != parameterArray[0])
rho_has_changed = TRUE;
if (param_a != parameterArray[1])
a_has_changed = TRUE;
if (param_b != parameterArray[2])
b_has_changed = TRUE;
if (param_c != parameterArray[3])
c_has_changed = TRUE;
if (theta != parameterArray[4])
theta_has_changed = TRUE;
rho = parameterArray[0];
param_a = parameterArray[1];
param_b = parameterArray[2];
param_c = parameterArray[3];
theta = parameterArray[4];
/* Check if network has been modified */
if (NetModified || (TopoSortID != ART2_TOPO_TYPE)) {
(void) kr_topoSort (ART2_TOPO_TYPE);
ret_code = KernelErrorCode;
if (ret_code != KRERR_NO_ERROR) {
NetModified = TRUE;
return (ret_code);
}
NetModified = FALSE;
}
/* get pointers to resp. first elements of each layer in topo_ptr_array */
topo_ptr = topo_ptr_array+1;
for (i=0; i<=9; i++) {
topo_layer[i] = topo_ptr;
do {
} while (*topo_ptr++ != NULL);
}
/* Check if input pattern changed since last call to this function */
if (krart_inp_pat_changed(topo_layer[0])) {
inp_pat_changed = TRUE;
krart_save_inp_pat(topo_layer[0]);
}
/* Read out value of parameter d from bias field of any unit. The
value has been written into the bias field by the init-function */
param_d = (*(topo_ptr_array+1))->bias;
/* Check values of the parameters */
if ((rho < 0.0) || (rho > 1.0) || (param_a <= 0.0) || (param_b <= 0.0) ||
((param_c*param_d)/(1-param_d) > 1.0) ||(theta < 0.0) || (theta > 1.0)){
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* if one of the parameters had changed from last to this call
of this update function then reinitialize the values of the i_act
field of the unit structure, set the weights of the relevant links and
reset the activations of all non input units */
if (rho_has_changed || a_has_changed || b_has_changed ||
c_has_changed || theta_has_changed || inp_pat_changed){
ret_code = kra2_set_params (rho,param_a,param_b,param_c,param_d,theta);
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
ret_code = kra2_init_propagate();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
kra2_init_pattern();
}
/* Push activation of input units to their output value.
This is important for the first cycle. */
topo_ptr = topo_layer[ART2_INP_LAY-1];
unit_ptr = *topo_ptr;
while (unit_ptr != NULL) {
if (unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
} else {
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
topo_ptr++;
unit_ptr = *topo_ptr;
}
/* compute vector norms */
kra2_compute_norms();
/* save old activation values of f1-units */
kra2_save_for_stability_check ();
/* Propagate */
krart_prop_synch ();
/* Get winner */
winner_ptr = krart_get_winner (topo_layer[ART2_REC_LAY-1], param_d);
/* Check F1 stability */
kra2_check_f1_stability ();
/* Check reset */
kra2_checkReset ();
return (ret_code);
}
/*****************************************************************************
FUNCTION : UPDATE_ART2_Propagate
PURPOSE :
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_ART2_Propagate(float *parameterArray, int NoOfParams)
{
krui_err ret_code = KRERR_NO_ERROR;
int i;
struct Unit *winner_ptr; /* recogn. unit which is the winner of w.t.a */
TopoPtrArray topo_layer[12]; /* topo_layer[0] : *first input unit
topo_layer[1] : *first w unit
topo_layer[2] : *first x unit
topo_layer[3] : *first u unit
topo_layer[4] : *first v unit
topo_layer[5] : *first p unit
topo_layer[6] : *first q unit
topo_layer[7] : *first r unit
topo_layer[8] : *first rec. unit
topo_layer[10] : *first local reset
unit */
TopoPtrArray topo_ptr;
FlintType rho, param_a, param_b, param_c, param_d, theta;
/* Check number of incoming parameters */
if (NoOfParams < 5) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
rho = parameterArray[0];
param_a = parameterArray[1];
param_b = parameterArray[2];
param_c = parameterArray[3];
theta = parameterArray[4];
/* Check if network has been modified or learning function has just
been changed */
if (NetModified || (TopoSortID != ART2_TOPO_TYPE)) {
(void) kr_topoSort (ART2_TOPO_TYPE);
ret_code = KernelErrorCode;
if (ret_code != KRERR_NO_ERROR) {
NetModified = TRUE;
return (ret_code);
}
NetModified = FALSE;
}
/* Read out value of parameter d from bias field of any unit. The
value has been written into the bias field by the init-function */
param_d = (*(topo_ptr_array+1))->bias;
/* Check values of the parameters */
if ((rho < 0.0) || (rho > 1.0) ||(param_a <= 0.0) || (param_b <= 0.0) ||
((param_c*param_d)/(1-param_d)>1.0) || (theta<0.0) || (theta>1.0)){
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
ret_code = kra2_set_params (rho, param_a, param_b, param_c, param_d, theta);
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
ret_code = kra2_init_propagate ();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
/* get pointers to resp. first elements of each layer in topo_ptr_array */
topo_ptr = topo_ptr_array+1;
for (i=0; i<=9; i++){
topo_layer[i] = topo_ptr;
do {
} while (*topo_ptr++ != NULL);
}
/* initialize the unit activations of the whole net */
ret_code = krart_reset_activations();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
/* initialize of ART2 Simulator for new pattern */
kra2_init_pattern ();
/* repeat synchronous propagation and look for winner until pattern is
classified or network tells us, that pattern is not classifiable */
do {
/* compute vector norms */
kra2_compute_norms();
/* save old activation values of f1-units */
kra2_save_for_stability_check ();
/* 1 propagation step (all units push their information onto
their output and calculate their new activation. */
krart_prop_synch ();
/* look for the recognition unit with the highest activation returns
a NULL pointer if all recognition units have activation 0.0 */
winner_ptr = krart_get_winner (topo_layer[ART2_REC_LAY-1], param_d);
/* Check if F1-Layer is stable */
kra2_check_f1_stability();
/* Check Reset */
kra2_checkReset ();
} while (!(ART2_CLASSIFIED) && !(ART2_NOT_CLASSIFIABLE));
return (ret_code);
}
/*****************************************************************************
FUNCTION : UPDATE_ARTMAP_syncPropagate
PURPOSE : ARTMAP update function which does exactly the same as the normal
synchronous propagate function except that additionally the winner
of the ARTMAP recognition layer is calculated.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_ARTMAP_syncPropagate(float *parameterArray, int NoOfParams)
{
krui_err ret_code = KRERR_NO_ERROR;
int i;
struct Unit *winner_ptr_a; /* the winner of wta of ARTa */
struct Unit *winner_ptr_b; /* the winner of w.t.a of ARTb */
struct Unit *unit_ptr;
TopoPtrArray topo_layer[14]; /* topo_layer[0] : *first input unit ARTa
topo_layer[1] : *first comp. unit ARTa
topo_layer[2] : *first rec. unit ARTa
topo_layer[3] : *first delay unit ARTa
topo_layer[4] : *first local reset unit ARTa
topo_layer[5] : *first special unit ARTa
(classified_unit)
topo_layer[6] : *first input unit ARTb
topo_layer[7] : *first comp. unit ARTb
topo_layer[8] : *first rec. unit ARTb
topo_layer[9] : *first delay unit ARTb
topo_layer[10]: *first local reset unit ARTb
topo_layer[11]: *first special unit ARTb
(classified_unit)
topo_layer[12]: *first map unit
topo_layer[13]: *first special map unit */
TopoPtrArray topo_ptr;
static float rho_a = -1.0;
static float rho_b = -1.0;
static float rho = -1.0;
bool inp_pat_changed = FALSE;
bool rho_has_changed = FALSE;
/* Check vigilance parameter */
if (NoOfParams < 3) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* Check if rho has changed from last to actual call of this update function
If rho has changed, then put new activation value into unit rho */
if ((rho_a != parameterArray[0]) || (rho_b != parameterArray[1]) ||
(rho != parameterArray[2]))
rho_has_changed = TRUE;
rho_a = parameterArray[0];
rho_b = parameterArray[1];
rho = parameterArray[2];
if((rho_a<0.0) || (rho_a>1.0) || (rho_b<0.0) || (rho_b>1.0) ||
(rho<0.0) || (rho>1.0)){
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* Check if network has been modified or learn func has just been changed */
if (NetModified || (TopoSortID != ARTMAP_TOPO_TYPE)) {
(void) kr_topoSort (ARTMAP_TOPO_TYPE);
ret_code = KernelErrorCode;
if (ret_code != KRERR_NO_ERROR) {
NetModified = TRUE;
return (ret_code);
}
NetModified = FALSE;
}
/* get pointers to resp. first elements of each layer in topo_ptr_array */
topo_ptr = topo_ptr_array+1;
for (i=0; i<=13; i++) {
topo_layer[i] = topo_ptr;
do {
} while (*topo_ptr++ != NULL);
}
/* Check if input pattern changed since last call to this function */
if (krart_inp_pat_changed(topo_layer[0]) ||
krart_inp_pat_changed(topo_layer[6])){
inp_pat_changed = TRUE;
krart_save_inp_pat(topo_layer[0]);
krart_save_inp_pat(topo_layer[6]);
}
/* Push activation of input units to their output value.
This is important for the first cycle. */
/* inpa - units */
topo_ptr = topo_layer[0];
for (unit_ptr = *topo_ptr; *topo_ptr != NULL; unit_ptr = *++topo_ptr) {
if (unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
} else {
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
}
topo_ptr = topo_layer[6];
for (unit_ptr = *topo_ptr; *topo_ptr != NULL; unit_ptr = *++topo_ptr) {
if (unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
} else {
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
}
/* if rho or input pattern had changed from last to this call of this
update function then reinitialize the values of the i_act field of the
unit structure and reset the activations of all non input units */
if (rho_has_changed || inp_pat_changed) {
ret_code = kram_init_i_act (rho_a, rho_b, rho);
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
ret_code = krart_reset_activations ();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
}
/* 1 propagation step (all units push their information onto
their output and calculate their new activation. */
krart_prop_synch ();
/* look for the recognition unit with the highest activation returns a
NULL pointer if all recognition units have activation 0.0 */
winner_ptr_a = krart_get_winner (topo_layer[2],1.0);
winner_ptr_b = krart_get_winner (topo_layer[8],1.0);
return (ret_code);
}
/*****************************************************************************
FUNCTION : UPDATE_ARTMAP_Propagate
PURPOSE : ARTMAP Update function for updating until a stable state is
reached, e.g. either the 'classified' unit is on or the 'not
classifiable' unit is.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_ARTMAP_Propagate(float *parameterArray, int NoOfParams)
{
krui_err ret_code = KRERR_NO_ERROR;
int i;
struct Unit *winner_ptr_a; /* the winner of w.t.a of ARTa */
struct Unit *winner_ptr_b; /* the winner of w.t.a of ARTb */
TopoPtrArray topo_layer[14]; /* topo_layer[0] : *first input unit ARTa
topo_layer[1] : *first comp. unit ARTa
topo_layer[2] : *first rec. unit ARTa
topo_layer[3] : *first delay unit ARTa
topo_layer[4] : *first local reset unit ARTa
topo_layer[5] : *first special unit ARTa
(classified_unit)
topo_layer[6] : *first input unit ARTb
topo_layer[7] : *first comp. unit ARTb
topo_layer[8] : *first rec. unit ARTb
topo_layer[9] : *first delay unit ARTb
topo_layer[10]: *first local reset unit ARTb
topo_layer[11]: *first special unit ARTb
(classified_unit)
topo_layer[12]: *first map unit
topo_layer[13]: *first special map unit */
TopoPtrArray topo_ptr;
float rho_a;
float rho_b;
float rho;
/* Check vigilance parameters */
if (NoOfParams < 3) {
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
rho_a = parameterArray[0];
rho_b = parameterArray[1];
rho = parameterArray[2];
if ((rho_a < 0.0) || (rho_a > 1.0) || (rho_b < 0.0) ||
(rho_b > 1.0) || (rho < 0.0) || (rho > 1.0)){
ret_code = KRERR_PARAMETERS;
return (ret_code);
}
/* Check if network has been modified or learn func has just been changed */
if (NetModified || (TopoSortID != ARTMAP_TOPO_TYPE)) {
(void) kr_topoSort (ARTMAP_TOPO_TYPE);
ret_code = KernelErrorCode;
if (ret_code != KRERR_NO_ERROR) {
NetModified = TRUE;
return (ret_code);
}
NetModified = FALSE;
}
ret_code = kram_init_i_act (rho_a, rho_b, rho);
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
/* get pointers to resp. first elements of each layer in topo_ptr_array */
topo_ptr = topo_ptr_array+1;
for (i=0; i<=13; i++) {
topo_layer[i] = topo_ptr;
do {
} while (*topo_ptr++ != NULL);
}
/* initialize activations of non input units */
ret_code = krart_reset_activations ();
if (ret_code != KRERR_NO_ERROR)
return (ret_code);
do {
/* 1 propagation step (all units push their information onto
their output and calculate their new activation. */
krart_prop_synch ();
/* look for the recognition unit with the highest activation
returns a NULL pointer if all recognition units have
activation 0.0 */
winner_ptr_a = krart_get_winner (topo_layer[2],1.0);
winner_ptr_b = krart_get_winner (topo_layer[8],1.0);
} while (!(ARTMAP_CLASSIFIED) && !(ARTMAP_NOT_CLASSIFIABLE));
return (ret_code);
}
/*****************************************************************************
FUNCTION : UPDATE_CC_Propagate
PURPOSE : Propagates a pattern through the net after pressing the test
button.
NOTES :
UPDATE : 5.2.93
******************************************************************************/
krui_err UPDATE_CC_Propagate(float parameterArray[], int NoOfParams)
{
register struct Unit *inputUnitPtr,*outputUnitPtr,*hiddenUnitPtr,*unitPtr;
register int dummy,o;
if(NetModified || LearnFuncHasChanged) {
NoOfInputUnits = NoOfHiddenUnits = NoOfOutputUnits = 0;
FOR_ALL_UNITS(unitPtr) {
if(IS_INPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfInputUnits++;
}
if(IS_HIDDEN_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfHiddenUnits++;
}
if(IS_OUTPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfOutputUnits++;
}
}
cc_update = 1;
KernelErrorCode = cc_deleteAllSpecialUnits();
ERROR_CHECK;
KernelErrorCode = kr_topoSort(TOPOLOGICAL_CC);
ERROR_CHECK;
KernelErrorCode = cc_setPointers();
ERROR_CHECK;
NetModified = FALSE;
LearnFuncHasChanged = FALSE;
}
FOR_ALL_INPUT_UNITS(inputUnitPtr,dummy){
if(inputUnitPtr->out_func == OUT_IDENTITY) {
inputUnitPtr->Out.output = inputUnitPtr->act;
}else{
inputUnitPtr->Out.output =
(*inputUnitPtr->out_func) (inputUnitPtr->act);
}
}
FOR_ALL_HIDDEN_UNITS(hiddenUnitPtr,dummy) {
hiddenUnitPtr->act = (*hiddenUnitPtr->act_func) (hiddenUnitPtr);
if(hiddenUnitPtr->out_func == OUT_IDENTITY) {
hiddenUnitPtr->Out.output = hiddenUnitPtr->act;
}else{
hiddenUnitPtr->Out.output =
(*hiddenUnitPtr->out_func) (hiddenUnitPtr->act);
}
}
FOR_ALL_OUTPUT_UNITS(outputUnitPtr,o) {
outputUnitPtr->act = (*outputUnitPtr->act_func) (outputUnitPtr);
if(outputUnitPtr->out_func == OUT_IDENTITY) {
outputUnitPtr->Out.output = outputUnitPtr->act;
}else{
outputUnitPtr->Out.output =
(*outputUnitPtr->out_func) (outputUnitPtr->act);
}
}
return(KRERR_NO_ERROR);
}
/*****************************************************************************
FUNCTION : UPDATE_RCC_Propagate
PURPOSE : Propagates a pattern through the net after pressing the test
button.
NOTES :
UPDATE : 5.2.93
******************************************************************************/
krui_err UPDATE_RCC_Propagate(float parameterArray[], int NoOfParams)
{
register struct Unit *inputUnitPtr,*outputUnitPtr,*hiddenUnitPtr,*unitPtr;
register int dummy,o;
static int oldNoOfPatterns=0;
if(NetModified || (krui_getNoOfPatterns() != oldNoOfPatterns) ||
LearnFuncHasChanged) {
KernelErrorCode = rcc_searchRecurrentLinks();
ERROR_CHECK;
rcc_manageResetArray(0,kr_TotalNoOfPattern()-1,1);
oldNoOfPatterns = krui_getNoOfPatterns();
NoOfInputUnits = NoOfHiddenUnits = NoOfOutputUnits = 0;
FOR_ALL_UNITS(unitPtr) {
if(IS_INPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfInputUnits++;
}
if(IS_HIDDEN_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfHiddenUnits++;
}
if(IS_OUTPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfOutputUnits++;
}
}
cc_update = 1;
KernelErrorCode = cc_deleteAllSpecialUnits();
ERROR_CHECK;
KernelErrorCode = kr_topoSort(TOPOLOGICAL_RCC);
ERROR_CHECK;
KernelErrorCode = cc_setPointers();
ERROR_CHECK;
LearnFuncHasChanged = FALSE;
NetModified = FALSE;
}
if (((int)reset[rcc_currentPattern]) == 1) {
printf("New pattern starts \n");
}
FOR_ALL_INPUT_UNITS(inputUnitPtr,dummy){
if(inputUnitPtr->out_func == OUT_IDENTITY) {
inputUnitPtr->Out.output = inputUnitPtr->act;
}else{
inputUnitPtr->Out.output =
(*inputUnitPtr->out_func) (inputUnitPtr->act);
}
}
FOR_ALL_HIDDEN_UNITS(hiddenUnitPtr,dummy) {
hiddenUnitPtr->lln = reset[rcc_currentPattern];
hiddenUnitPtr->act = (*hiddenUnitPtr->act_func) (hiddenUnitPtr);
if(hiddenUnitPtr->out_func == OUT_IDENTITY) {
hiddenUnitPtr->Out.output = hiddenUnitPtr->act;
}else{
hiddenUnitPtr->Out.output =
(*hiddenUnitPtr->out_func) (hiddenUnitPtr->act);
}
}
FOR_ALL_OUTPUT_UNITS(outputUnitPtr,o) {
outputUnitPtr->lln = reset[rcc_currentPattern];
outputUnitPtr->act = (*outputUnitPtr->act_func) (outputUnitPtr);
if(outputUnitPtr->out_func == OUT_IDENTITY) {
outputUnitPtr->Out.output = outputUnitPtr->act;
}else{
outputUnitPtr->Out.output =
(*outputUnitPtr->out_func) (outputUnitPtr->act);
}
}
return(KRERR_NO_ERROR);
}
/*****************************************************************************
FUNCTION : UPDATE_DLVQ_Propagate
PURPOSE :
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_DLVQ_Propagate(float parameterArray[], int NoOfParams)
{
struct Unit *inputUnitPtr,*hiddenUnitPtr,*maxActivatedUnitPtr=NULL;
double maxAct,act;
int i,h,startPattern,endPattern,d1,d2,d3,generatedNewUnit,noOfLinks;
if(newPatternsLoaded){
newPatternsLoaded = 0;
startPattern = 0;
/* endPattern = krui_getNoOfPatterns()-1;*/
endPattern = kr_TotalNoOfSubPatPairs()-1;
KernelErrorCode = getNoOfClasses(startPattern,endPattern);
ERROR_CHECK;
normPatterns(startPattern,endPattern);
allocInitialUnitArray();
initInitialUnitArray(startPattern,endPattern);
}
if(NetModified || LearnFuncHasChanged) {
NoOfInputUnits = NoOfHiddenUnits = NoOfOutputUnits = 0;
FOR_ALL_UNITS(unitPtr) {
if(IS_INPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfInputUnits++;
}
if(IS_HIDDEN_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfHiddenUnits++;
}
if(IS_OUTPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
NoOfOutputUnits++;
}
}
if(NoOfOutputUnits != 1){
return(DLVQ_ERROR3); /* Wrong no. of output units */
}
allocArrays();
KernelErrorCode = kr_topoSort(TOPOLOGICAL_FF);
ERROR_CHECK;
KernelErrorCode = dlvq_setPointers();
ERROR_CHECK;
krui_getNetInfo(&d1,&noOfLinks,&d2,&d3);
if(noOfLinks != NoOfInputUnits * NoOfHiddenUnits + NoOfHiddenUnits) {
return(DLVQ_ERROR4); /* wrong topology */
}
generateMissingClassHiddenUnits(&generatedNewUnit);
if(generatedNewUnit) {
return(DLVQ_ERROR5); /* There is not a class for every unit */
}
NetModified = FALSE;
LearnFuncHasChanged = FALSE;
}
FOR_ALL_INPUT_UNITS(inputUnitPtr,i){
inputUnitPtr->Out.output = inputUnitPtr->act;
}
maxAct = -1.0;
FOR_ALL_HIDDEN_UNITS(hiddenUnitPtr,h) {
hiddenUnitPtr->Out.output = hiddenUnitPtr->act = act = 0.0;
FOR_ALL_LINKS(hiddenUnitPtr,linkPtr) {
act += linkPtr->weight * linkPtr->to->Out.output;
}
if(maxAct < act){
maxAct = act;
maxActivatedUnitPtr = hiddenUnitPtr;
}
}
maxActivatedUnitPtr->Out.output = maxActivatedUnitPtr->act = 1.0;
(*FirstOutputUnitPtr)->Out.output =
(*FirstOutputUnitPtr)->act = maxActivatedUnitPtr->bias;
return(KRERR_NO_ERROR);
}
/*****************************************************************************
FUNCTION : UPDATE_BPTT
PURPOSE : Backpropagation through time synchronous order using activity
buffer for each unit.
RETURNS :
NOTES : The "TEST" button in the remote panel first increases the pattern
number, copies the input pattern to the input units and,
depending on the setting of the "SHOW" button,
- does not copy the output pattern with setting "none"
- copies the output pattern to unit_ptr->act with setting
"activation"
- copies the output pattern to unit_ptr->act and
unit_ptr->Out.output with setting "output"
An all-zero-input pattern for reset is only effective using
"TEST" if the current pattern is the pattern immediatly before
the reset pattern.
UPDATE :
******************************************************************************/
krui_err UPDATE_BPTT(float *parameterArray, int NoOfParams)
{
krui_err ret_code;
register struct Unit *unit_ptr;
register TopoPtrArray topo_ptr;
register TopoPtrArray first_hidden_ptr;
int all_zero_input=1; /* flag to reset net-copies */
int done_hidden;
if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
/* Net has been modified or topologic array isn't initialized */
/* any connected topology allowed */
/* count the no. of I/O units and check the patterns */
ret_code = kr_IOCheck();
if (ret_code < KRERR_NO_ERROR)
return( ret_code );
/* sort units by ''topologic type'',
criterion is visibility (input,hidden,output), not topology */
ret_code = kr_topoSort( TOPOLOGIC_TYPE );
if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
return( ret_code );
NetModified = FALSE;
}
/* check all zero pattern in input layer => reset net_activities */
topo_ptr = topo_ptr_array;
while ((unit_ptr = *++topo_ptr) != NULL) {
unit_ptr->Out.output = unit_ptr->act;
if(fabs(unit_ptr->act)>0.0001) all_zero_input = 0; /* no reset-input */
}
first_hidden_ptr = topo_ptr;
if (all_zero_input) { /* clear netact-copies */
FOR_ALL_UNITS( unit_ptr ) unit_ptr->i_act = 0.0;
}
/* copy last unit_ptr->i_act to unit_ptr->Out.output */
/* one step back in time, make most recent activity
visible in unit_ptr->Out.output for subsequent calls to act_func */
while ((unit_ptr = *++topo_ptr) != NULL) { /* hidden layer */
unit_ptr->Out.output = unit_ptr->i_act; }
while ((unit_ptr = *++topo_ptr) != NULL) { /* output layer */
unit_ptr->Out.output = unit_ptr->i_act; }
/* calculate new activities for hidden and output units */
/* point to first hidden unit */
topo_ptr = first_hidden_ptr;
done_hidden=0;
while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
if (unit_ptr == NULL) {
done_hidden = 1;
}else{
/* calc act using i_act copied to Out.output, SYNCHRONOUS UPDATE:
don't update Out.output while updating units, wait until all
units are processed */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
}
/* calculate new Out.output values from act by calling out_func,
and save values in i_act (since they may be disturbed by show pattern)*/
/* point to first hidden unit */
topo_ptr = first_hidden_ptr;
done_hidden=0;
while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
if (unit_ptr == NULL) {
done_hidden = 1;
}else{
if (unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
unit_ptr->i_act = unit_ptr->Out.output;
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_BAM
PURPOSE :
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_BAM(float *parameterArray, int NoOfParams)
{
krui_err ret_code;
register struct Unit *unit_ptr;
register TopoPtrArray topo_ptr;
register TopoPtrArray first_hidden_ptr;
int all_zero_input=1; /* flag to reset net-copies */
int done_hidden;
FlintType new_output;
if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
/* Net has been modified or topologic array isn't initialized */
/* any connected topology allowed */
/* count the no. of I/O units and check the patterns */
ret_code = kr_IOCheck();
if (ret_code < KRERR_NO_ERROR)
return( ret_code );
/* sort units by ''topologic type'',
criterion is visibility (input,hidden,output), not topology */
ret_code = kr_topoSort( TOPOLOGIC_TYPE );
if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
return( ret_code );
NetModified = FALSE;
}
/* Search hidden Units */
topo_ptr = topo_ptr_array;
while ((unit_ptr = *++topo_ptr) != NULL) {
}
first_hidden_ptr = topo_ptr;
/* calculate new Out.output values from act by calling out_func */
/* point to first hidden unit and remember the old ones*/
topo_ptr = first_hidden_ptr;
done_hidden=0;
while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
if (unit_ptr == NULL) {
done_hidden = 1;
}else{
unit_ptr->value_a = unit_ptr->Out.output;
if (unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
}
/* calculate new activities for hidden and output units */
/* point to first hidden unit */
topo_ptr = first_hidden_ptr;
done_hidden=0;
while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
if (unit_ptr == NULL) {
done_hidden = 1;
}else{
/* save new value and restore old value from output */
new_output = unit_ptr->Out.output;
unit_ptr->Out.output = unit_ptr->value_a;
/* calc act */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
/* restore new value */
unit_ptr->Out.output = new_output;
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_JE_Propagate
PURPOSE : update function for JORDAN / ELMAN networks
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_JE_Propagate (float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr ;
register TopoPtrArray topo_ptr, help_ptr ;
int ret_code, i ;
if (NetModified || (TopoSortID != TOPOLOGICAL_JE)){
/* network was modified or topologic array isn't initialized */
ret_code = kr_topoCheckJE () ;
if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
ret_code = kr_topoSort (TOPOLOGICAL_JE) ;
if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
NetModified = FALSE ;
}
topo_ptr = topo_ptr_array ;
/* calculate output of input units */
while ((unit_ptr = *++topo_ptr) != NULL){
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act ;
else
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
}
/* propagate hidden and output units */
for (i = 0 ; i < 2 ; i++){
while ((unit_ptr = *++topo_ptr) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act ;
else
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
}
}
/* update of context units */
help_ptr = topo_ptr ;
while ((unit_ptr = *++help_ptr) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
}
while ((unit_ptr = *++topo_ptr) != NULL){
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act ;
else
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
}
return (KRERR_NO_ERROR) ;
}
/*****************************************************************************
FUNCTION : UPDATE_JE_Special
PURPOSE : update function with dynamic pattern generation for JORDAN /
ELMAN networks
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_JE_Special (float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr ;
register TopoPtrArray topo_ptr, help_ptr ;
int ret_code, i ;
if (NetModified || (TopoSortID != TOPOLOGICAL_JE)){
/* network was modified or topologic array isn't initialized */
ret_code = kr_topoCheckJE () ;
if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
ret_code = kr_topoSort (TOPOLOGICAL_JE) ;
if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
NetModified = FALSE ;
}
if (NoOfInputUnits < NoOfOutputUnits) return (-1) ;
/* create new input pattern from the output of input and output units */
help_ptr = topo_ptr_array ;
while (*++help_ptr != NULL) ; /* skip input units */
while (*++help_ptr != NULL) ; /* skip hidden units */
topo_ptr = topo_ptr_array ;
for (i = 1 ; i <= NoOfInputUnits ; i++)
if (i <= NoOfInputUnits - NoOfOutputUnits)
(*(topo_ptr+i))->act = (*(topo_ptr+i+NoOfOutputUnits))->Out.output;
else
(*(topo_ptr+i))->act = (*++help_ptr)->Out.output ;
topo_ptr = topo_ptr_array ;
/* calculate output of input units */
while ((unit_ptr = *++topo_ptr) != NULL){
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act ;
else
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
}
/* propagate hidden and output units */
for (i = 0 ; i < 2 ; i++){
while ((unit_ptr = *++topo_ptr) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act ;
else
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
}
}
/* synchronous update of context units */
help_ptr = topo_ptr ;
while ((unit_ptr = *++help_ptr) != NULL){
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
}
while ((unit_ptr = *++topo_ptr) != NULL){
if (unit_ptr->out_func == OUT_IDENTITY)
unit_ptr->Out.output = unit_ptr->act ;
else
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
}
return (KRERR_NO_ERROR) ;
}
/*****************************************************************************
FUNCTION : UPDATE_syncPropagateHop
PURPOSE : synchronous propagation for Hopfield
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
krui_err UPDATE_syncPropagateHop(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
int unit_no;
/* update unit outputs first, because the patterns set only */
/* the activations of the input units, and they would be overwritten */
FOR_ALL_UNITS( unit_ptr ) {
if UNIT_IN_USE(unit_ptr) {
if (*unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{ /* the default way */
unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
}
}
}
/* update unit activations second */
/* first non input, then input units, so function can be used for BAM too */
FOR_ALL_UNITS( unit_ptr ){
if (UNIT_IN_USE(unit_ptr)&&!IS_INPUT_UNIT(unit_ptr))
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
}
/* output update of non input units (for resultfile) */
FOR_ALL_UNITS( unit_ptr ) {
if (UNIT_IN_USE(unit_ptr) && !IS_INPUT_UNIT(unit_ptr)) {
if (*unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{ /* the default way */
unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
}
}
}
/* update input units */
FOR_ALL_UNITS( unit_ptr ){
if (UNIT_IN_USE(unit_ptr)&&IS_INPUT_UNIT(unit_ptr))
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
}
/* output update of input units (for resultfile) */
FOR_ALL_UNITS( unit_ptr ) {
if (UNIT_IN_USE(unit_ptr) && IS_INPUT_UNIT(unit_ptr)) {
if (*unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{ /* the default way */
unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
}
}
}
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_FixAct_Hop
PURPOSE : synchronous update with fixed activity
RETURNS :
NOTES : the units updated are given the activity 1 the others 0
UPDATE :
******************************************************************************/
krui_err UPDATE_FixAct_Hop(float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
FlintType sum, aux, min;
ACT_FUNC_DEFS /* defines link- and site-pointer */
register int i;
int NoOfOnes, where;
int unit_no;
struct Unit **unitsToUpdate;
FlintType *netInputArray;
short is_to_update;
NoOfOnes = parameterArray[0]; /* the fixed Number of 1 */
/* init netInputArray and unitsToUpdate */
netInputArray = (FlintType *) calloc(NoOfOnes, sizeof(FlintType));
unitsToUpdate = (struct Unit * *) calloc(NoOfOnes, sizeof( struct Unit *));
for(i=0; i< NoOfOnes-1; i++) {
unitsToUpdate[i] = NULL;
netInputArray[i] = -9e37;
}
FOR_ALL_UNITS(unit_ptr) {
if UNIT_IN_USE(unit_ptr) {
if (*unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{/* the default way */
unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
}
}
}
/* find the units to update (their nr. is given by "NoOfOnes") */
FOR_ALL_UNITS(unit_ptr) {
/* get the netInput of this unit */
sum = 0.0; aux = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr )){
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
}
/* get the min of netInputArray */
min = netInputArray[0];
where = 0;
for(i = 1; i <= NoOfOnes - 1; i++) {
if( netInputArray[i] < min) {
min = netInputArray[i];
where = i;
}
}
/* replace it */
if( sum > min ){
netInputArray[where] = sum;
unitsToUpdate[where] = unit_ptr;
}
}
/* update unit activations */
FOR_ALL_UNITS(unit_ptr){
unit_ptr->act = 0.0;
}
for(i=0; i<= NoOfOnes-1; i++){
unit_ptr = unitsToUpdate[i];
unit_ptr->act = 1.0;
}
/* output update for resultfile */
FOR_ALL_UNITS(unit_ptr) {
if UNIT_IN_USE(unit_ptr) {
if (*unit_ptr->out_func == OUT_IDENTITY) {
unit_ptr->Out.output = unit_ptr->act;
}else{/* the default way */
unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
}
}
}
free(netInputArray);
free(unitsToUpdate);
return( KRERR_NO_ERROR );
}
/*****************************************************************************
FUNCTION : UPDATE_RM_Propagate
PURPOSE :
RETURNS :
NOTES : McClelland & Rummelhart's update rule
UPDATE :
******************************************************************************/
krui_err UPDATE_RM_Propagate (float *parameterArray, int NoOfParams)
{
register struct Unit *unit_ptr;
int t, NoTimes;
NoTimes = parameterArray[0];
for (t=0; t < NoTimes; ++t){
/* update unit activations */
FOR_ALL_UNITS( unit_ptr )
if UNIT_IN_USE( unit_ptr )
if ( !IS_INPUT_UNIT( unit_ptr))
/* unit isn't an input unit and is in use and enabled */
unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
/* update unit outputs */
FOR_ALL_UNITS( unit_ptr )
if UNIT_IN_USE( unit_ptr )
if (unit_ptr->out_func == OUT_IDENTITY)
/* identity output function: don't call output function */
unit_ptr->Out.output = unit_ptr->act;
else
/* calculate unit's output also */
unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
}
return( KRERR_NO_ERROR );
}
/*#################################################
GROUP: User Defined Update Functions
#################################################*/